/**
@author		Jong Min, Lee
@date		  10/01/2014
@breif		dicom instance class 

copyright(c) Tae Young Soft. All right reserved. 2014
*/
#pragma once

#include <vector>

#include "Taurus_Util/Macros.h"
#include "Taurus_DcmData/Defines.h"

//forward declarations
class IInstanceInfo;
class CDcmSeries;
class CDcmFrame;

/**
@brief		dicom instance class
*/
class TAURUS_DCMDATA_EXPORT CDcmInstance
{
private:
  /**
  @brief		default constructor
  */
  CDcmInstance();

  DISALLOW_COPY_AND_ASSIGN(CDcmInstance);

/************************************************************************/
/* public data members                                                  */
/************************************************************************/
public:
  friend class CDcmInstanceProducer;

  /**
  @brief		destructor
  */
  ~CDcmInstance();

  /**
  @brief		increase reference count by 1
  */
  inline void increaseRefCount()
  {
    m_theRefCount++;
  }

  /**
  @brief		decrease reference count by 1
  */
  inline void decreaseRefCount()
  {
    m_theRefCount--;
  }

  /**
  @brief		get reference count
  @return   reference count
  */
  inline int getRefCount() const
  {
    return m_theRefCount;
  }

  /**
  @brief		get poiner to parent dcm series
  @return		pointer to parent dcm series if dcm instance has it, nullptr if not
  */
  inline CDcmSeries* getParent() const
  {
    return m_theParent;
  }

  /**
  @brief		set pointer to parent dcm series
  @param		parent pointer to dcm series to be parent
  */
  inline void setParent(CDcmSeries* parent)
  {
    m_theParent = parent;
  }

  /**
  @brief		access to instance key
  @return		null-terminated string represents instance key
  */
  inline const TCHAR* getKey() const
  {
    return m_theKey;
  }

  /**
  @brief		access to SOP Class UID
  @return		null-terminated string represents SOP Class UID
  */
  inline const TCHAR* getSOPClassUID() const
  {
    return m_theSOPClassUID;
  }

  /**
  @brief		get the number of dcm frames
  @return		the number of dcm frames
  */
  unsigned int getNumFrames() const;

  /**
  @brief		access a dcm frame
  @param		index the index number of dcm frame
  @return		pointer to dcm frame if found, nullptr if not
  */
  const CDcmFrame* getFrame(const unsigned int index) const;
  CDcmFrame* getFrame(const unsigned int index);

/************************************************************************/
/* private function members                                             */
/************************************************************************/
private:
  /**
  @brief		initialize dcm instance to default
  */
  void init();

  /**
  @brief		destroy dcm instance. this method should only be used in destructor
  */
  void destroy();

  /**
  @brief		remove all frames belong to this
  */
  void removeAllFrames();


/************************************************************************/
/* private data members                                                 */
/************************************************************************/
private:

  //reference count
  int m_theRefCount;

  //parent dicom series
  CDcmSeries* m_theParent;

  //instance key
  CString m_theKey;

  //sop class uid
  CString m_theSOPClassUID;

  //dicom frames
  std::vector<CDcmFrame*> m_theFrames;
};

/**
@brief		dcm instance producer class
*/
class TAURUS_DCMDATA_EXPORT CDcmInstanceProducer
{
public:
  /**
  @brief		create dcm instance by uisng instance information
  @param		instanceInfo instance information
  @param    parent pointer to dcm series to be parent
  @param    outInstance variable in which pointer to new dcm instance is stored
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  static DWORD produce(IInstanceInfo& instanceInfo,
                       CDcmSeries* parent,
                       CDcmInstance* outInstance);
};
                        